/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jsonParser;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import client.SystemProperties;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;

/**
 * Met deze klasse kun je de data binnenhalen van de server en scheiden in drie
 * soorten: alarmen, analoge sensoren en binaire sensoren. Zolang een socket
 * alive is zullen sensorwaardes in de ArrayListen worden geladen. De alarmen,
 * binaire en analoge sensoren zitten allemaal in een aparte ArrayList zodat je
 * makkelijk er doorheen kunt lopen en voor enkle waarde een sensor kunt maken.
 * 
 * @author David de Hoop
 */
public class TCPSocket {
	String ipadress = "145.92.12.132";
	int portnumber = 81;
	String jsonString;

	private List<TCPSocketListener> listeners = new LinkedList<>();

	ArrayList<JSONObject> jsonArrayAlarm = new ArrayList<>();
	ArrayList<JSONObject> jsonArrayAnalogSensors = new ArrayList<>();
	ArrayList<JSONObject> jsonArrayBinarySensors = new ArrayList<>();

	public interface TCPSocketListener {
		/**
		 * Called when data of a TCPSocket has changed.
		 * 
		 * @param source
		 *            The TCPSocket whose data has changed.
		 */
		public void socketDataChanged(TCPSocket source);

		/**
		 * Called when a TCPSocket has received an alarm.
		 * 
		 * @param source
		 *            The TCPSocket who has received the alarm.
		 * @param alarmMessage
		 *            The alarm message of the alarm.
		 */
		public void alarmReceived(TCPSocket source, String alarm);
	}

	public void addTCPSocketListener(TCPSocketListener listener) {
		listeners.add(listener);
	}

	public void notifySocketDataChanged() {
		for (TCPSocketListener listener : listeners) {
			listener.socketDataChanged(this);
		}
	}
	
	private void notifyAlarmReceived(String alarmMessage) {
		for (TCPSocketListener listener : listeners) {
			listener.alarmReceived(this, alarmMessage);
		}
	}

	public void Socket() throws IOException {
		String ipAddress = SystemProperties.getServerIp();
		int portnumber = Integer.parseInt(SystemProperties.getServerPort());
		Socket TCPSocket = new Socket(ipAddress, portnumber);
		TCPSocket.setKeepAlive(true);

		DataInputStream inFromServer = new DataInputStream(
				TCPSocket.getInputStream());
		BufferedReader br = new BufferedReader(new InputStreamReader(
				inFromServer, "UTF-8"));

		while (true) {
			TCPSocket.getKeepAlive();
			jsonString = br.readLine();

			System.out.println(jsonString);

			JSONObject jsonStringObject = (JSONObject) JSONSerializer
					.toJSON(jsonString);

			if (jsonStringObject.get("alarm") != null) {
				JSONObject jsonAlarms = (JSONObject) jsonStringObject
						.get("alarm");
				jsonArrayAlarm.add(jsonAlarms);
				String alarmString = jsonAlarms.getString("alarmName");
				if (alarmString != null) {
					notifyAlarmReceived(alarmString);
				} else {
					System.out.println("Alarm parse error");
				}
			}

			else if (jsonStringObject.get("analogSensors") != null) {
				JSONArray jsonAnalogSensors = (JSONArray) jsonStringObject
						.get("analogSensors");
				for (int i = 0; i < jsonAnalogSensors.size(); i++) {
					JSONObject jsonObject = jsonAnalogSensors.getJSONObject(i);
					jsonArrayAnalogSensors.add(jsonObject);
				}

				if (jsonStringObject.get("binarySensors") != null) {
					JSONArray jsonBinarySensors = (JSONArray) jsonStringObject
							.get("binarySensors");
					for (int i = 0; i < jsonBinarySensors.size(); i++) {
						JSONObject jsonObject = jsonBinarySensors
								.getJSONObject(i);
						jsonArrayBinarySensors.add(jsonObject);
					}
				
				}
				notifySocketDataChanged();
			}
		}
	}

	public ArrayList<JSONObject> getJsonArrayAnalogSensors() {
		return jsonArrayAnalogSensors;
	}

	public ArrayList<JSONObject> getJsonArrayBinarySensors() {
		return jsonArrayBinarySensors;
	}
}
